package com.skp.shaphan.ui.buttons;

import gnu.java.net.LineInputStream;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;

import javax.swing.JButton;

import com.skp.job.ProjectJobException;
import com.skp.shaphan.ShaphanApp;
import com.skp.shaphan.ui.dialogs.ImportDialog;

public class ImportOkButton extends JButton implements ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3198756123987599845L;
	private ImportDialog dialog;
	public ImportOkButton(ImportDialog dialog) {
		super("Ok");
		this.dialog = dialog;
		this.addActionListener(this);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Connection conn = ShaphanApp.getMainWindow().getSqlEditor().getConnection().getConnection();
		String sqlStatement = "select * from " + dialog.getTablename();
		try {
			ResultSet results = buildResults(conn, sqlStatement);
			if(dialog.isFileExport()) {
				resultsFromFile(results);
			} else {
				ResultsToClipboard(results);
			}
		} catch (SQLException e1) {
			(new ProjectJobException(e1)).displayException();
		} catch (FileNotFoundException e1) {
			(new ProjectJobException(e1)).displayException();
		} catch (IOException e1) {
			(new ProjectJobException(e1)).displayException();
		}
		dialog.dispose();
	}
	
	private ResultSet buildResults(Connection conn, String sql) throws SQLException {
		PreparedStatement st = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
		return st.executeQuery();
	}
	
	private void resultsFromFile(ResultSet rs) throws SQLException, IOException {
		File inputFile = new File(dialog.getInputPath());
		LineInputStream input = new LineInputStream(new FileInputStream(inputFile));
		ArrayList<String> data = readRow(input);
		ResultSetMetaData meta = rs.getMetaData();
		long rowNum = 0;
		// I am getting an "Invalid Cursor Type: 1003" error -- I think rs.next() might fix it
		rs.next();
		while(data != null) {
			rowNum++;
			System.out.println("Inserting row " + rowNum);
			rs.moveToInsertRow();
			try {
				for(int x=0; x<data.size(); x++) {
					updateColumn(x + 1, data.get(x), rs, meta);
				}
			} catch (SQLException e) {
				throw new SQLException("Error updating row " + rowNum + "--" + e.getLocalizedMessage(), e);
			}
			rs.insertRow();
			data = readRow(input);
		}
		input.close();
	}
	
	private void updateColumn(int columnIndex, String value, ResultSet rs, ResultSetMetaData meta) throws SQLException {
		String columnName = meta.getColumnName(columnIndex);
		int columnType = meta.getColumnType(columnIndex); 
		System.out.println("  updating " + columnName + "(" + columnType + ") to " + value);
		if(columnType == Types.CHAR || columnType == Types.NCHAR || columnType == Types.NVARCHAR || columnType == Types.VARCHAR ) {
			if(value.length() > meta.getPrecision(columnIndex)) {
				value = value.substring(0, meta.getPrecision(columnIndex));
				System.out.println("     Truncating value to " + value);
			}
		}
		try {
			rs.updateObject(columnIndex, value);
		} catch (SQLException e) {
			throw new SQLException("Error updating field " + columnName + " to value + '" + value + "': " + e.getLocalizedMessage(), e);
		}
	}
	
	private ArrayList<String> readRow(LineInputStream input) throws IOException {
		String line = input.readLine();
		if(line == null) {
			return null;
		}
		line = line.trim();
		ArrayList<String> data = new ArrayList<String>();
		String field = "";
		boolean inField = false;
		while(!line.equals("")) {
			char c = line.charAt(0);
			line = line.substring(1);
			if(c == '\"') {
				inField = !inField;
				if(!inField) {
					line = line.trim();
				}
			} else if (c == ',') {
				if(inField) {
					field += c;
				} else {
					data.add(field);
					field = "";
					line = line.trim();
				}
			} else {
				field += c;
			}
		}
		if(field.length() > 0) {
			data.add(field);
		}
		return data;
	}

	private void ResultsToClipboard(ResultSet rs) throws SQLException {
		String output = "";
		ResultSetMetaData meta = rs.getMetaData();
		while(rs.next()) {
			for(int x=1; x<=meta.getColumnCount(); x++) {
				if(x > 1) {
					output += "\t";
				}
				output += rs.getObject(x).toString();
			}
			output += "\n";
		}
		Statement st = rs.getStatement();
		rs.close();
		st.close();
		
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		StringSelection contents = new StringSelection(output);
		clipboard.setContents(contents, ShaphanApp.getMainWindow().getClipboard());
	}
}
